﻿using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Threading;
using System.Data.Common;

namespace Petaframe.DataAccess
{

    //TODO: düzenle
    /// <summary>
    /// Her tabloya ait sınıf için oluşturulan sorguları önbelleğe alır. Thead safe olduğu için sorunsuzca multi thread ortamlarda kullanılabilir.
    /// </summary>
    /// <typeparam name="T">Tabloya ait sınıf tipi.</typeparam>
   //internal sealed class EntityQueryCache<T> 
   // {
   //      private static readonly Lazy<EntityQueryCache<T>> lazy = new Lazy<EntityQueryCache<T>>(() => new EntityQueryCache<T>());

   //      public static  EntityQueryCache<T> Instance { get { return lazy.Value; } }

   //     private EntityQueryCache() { }
    
   //     private readonly ConcurrentDictionary<T, Tuple<TableQueries, TableInfo>> cache = new ConcurrentDictionary<T, Tuple<TableQueries, TableInfo>>();

   //     public Tuple<TableQueries, TableInfo> GetTableQueriesAndInfo(T entity, IParameterBuilder _pb, IEscapeSqlIdentifier _es)
   //     {
   //         Tuple<TableQueries,TableInfo> _tuple;

   //         if (!cache.TryGetValue(entity, out _tuple))
   //         {
   //             TableInfo ti =new ClassDecomposer().ForEntity(entity,_pb,_es);
   //             TableQueries queries = new TableQueries(ti);
   //             cache.TryAdd(entity, new Tuple<TableQueries,TableInfo>(queries,ti));               
   //         }
   //         return _tuple;
   //     }
   // }

    /// <summary>
    /// Her tabloya ait sınıf için oluşturulan sorguları önbelleğe alır. Thead safe olduğu için sorunsuzca multi thread ortamlarda kullanılabilir.
    /// </summary>
    /// <typeparam name="T">Tabloya ait sınıf tipi.</typeparam>
   internal static class EntityQueryCache
   {
          

    //   private static readonly ConcurrentDictionary<string, Tuple<TableQueries, TableInfo>> cache = new ConcurrentDictionary<string, Tuple<TableQueries, TableInfo>>();
       private static readonly ConcurrentDictionary<string, TableInfo> queryCache = new ConcurrentDictionary<string, TableInfo>();

       /// <summary>
       /// Verilen class ismine göre class bilgilerini ve ilgili classa ait insert, update ,delete komutlarını önbellekten getirir.
       /// </summary>
       /// <param name="entity"></param>
       /// <param name="_pb"></param>
       /// <param name="_es"></param>
       /// <returns></returns>
       //public static Tuple<TableQueries, TableInfo> GetTableQueriesAndInfo(object entity, IParameterBuilder _pb, IEscapeSqlIdentifier _es)
       //{
       //    Tuple<TableQueries, TableInfo> _tuple;

       //    if (!cache.TryGetValue(entity.GetType().Name, out _tuple))
       //    {
       //        TableInfo ti = new ClassDecomposer().ForObject(entity, _pb, _es);
       //        TableQueries queries = new TableQueries(ti);
       //        _tuple = new Tuple<TableQueries, TableInfo>(queries, ti);
       //        cache.TryAdd(ti.ClassName,_tuple );
       //    }
       //    return _tuple;
       //}

       /// <summary>
       /// Verilen class ismine göre class bilgilerini ve ilgili classa ait insert, update ,delete komutlarını önbellekten getirir.
       /// </summary>
       public static TableInfo GetCachedTableInfo(object entity, IParameterBuilder _pb, IEscapeSqlIdentifier _es, DbProviderFactory factory)
       {
           TableInfo _info;

           if (!queryCache.TryGetValue(entity.GetType().Name, out _info))
           {
               _info = new ClassDecomposer().ForObject(entity, _pb, _es,factory);
              // TableQueries queries = new TableQueries(ti);
               //_tuple = new Tuple<TableQueries, TableInfo>(queries, ti);
               queryCache.TryAdd(_info.ClassName, _info);
           }
           return _info;
       }

       /// <summary>
       /// Verilen class tipine göre class bilgilerini ve ilgili classa ait insert, update ,delete komutlarını önbellekten getirir.
       /// </summary>
       public static TableInfo GetCachedTableInfo(Type entity, IParameterBuilder _pb, IEscapeSqlIdentifier _es, DbProviderFactory factory)
       {
           TableInfo _info;

           if (!queryCache.TryGetValue(entity.Name, out _info))
           {
               _info = new ClassDecomposer().ForType(entity, _pb, _es,factory);
               // TableQueries queries = new TableQueries(ti);
               //_tuple = new Tuple<TableQueries, TableInfo>(queries, ti);
               queryCache.TryAdd(_info.ClassName, _info);
           }
           return _info;
       }
   }
}
